package com.alangyun.remind.service.excel;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.alangyun.remind.BaseActor;
import com.alangyun.remind.error.MindException;

public abstract class AbstractExcelReader extends BaseActor implements ExcelReader {

	@Override
	public ParseResult read(String excelFilePath) {
		if(less2007(excelFilePath))
			return this.readXLS(excelFilePath);
		
		return this.readXLSX(excelFilePath);
	}

	@Override
	public ParseResult read(File excelFile) {
		if(less2007(excelFile.getAbsolutePath()))
			return this.readXLS(excelFile);
		
		return this.readXLSX(excelFile);
	}

	@Override
	public ParseResult readXLS(InputStream stream) {
		POIFSFileSystem poifsFileSystem = null;
		HSSFWorkbook book = null;

		ParseResult ret = null;
		try {
			poifsFileSystem = new POIFSFileSystem(stream); // 使用POI提供的方法得到excel的信息
			book = new HSSFWorkbook(poifsFileSystem);// 得到文档对象
			ret = readSheet(book.getSheetAt(0));
		} catch (Exception ex) {
			throw new MindException("解析Excel文件出错", ex);
		} finally {
			close(book);
			close(poifsFileSystem);
		}

		return ret;
	}

	@Override
	public ParseResult readXLSX(InputStream stream) {
		OPCPackage pkg = null;
		XSSFWorkbook xssfwb = null;

		ParseResult ret = null;

		try {
			pkg = OPCPackage.open(stream);
			xssfwb = new XSSFWorkbook(pkg);

			ret = readSheet(xssfwb.getSheetAt(0));
		} catch (Exception ex) {
			throw new MindException("解析Excel文件出错", ex);
		} finally {
			close(xssfwb);
			close(pkg);
		}

		return ret;
	}

	private boolean less2007(String filename) {
		int index = filename.lastIndexOf('.');
		
		if (index >= 0) {
			String ext = filename.substring(index + 1).toLowerCase();
			if ("xls".equals(ext) || "xlsx".equals(ext)) {
				return "xls".equals(ext);
			}
		}

		throw new IllegalArgumentException("未知的文件类型，请确认文件扩展名是否为.xls或者.xlsx文件类型");
	}

	private ParseResult readXLS(String excelFilePath) {
		return readXLS(new File(excelFilePath));
	}

	private ParseResult readXLSX(String excelFilePath) {
		return readXLSX(new File(excelFilePath));
	}

	private ParseResult readXLS(File excelFile) {
		InputStream is = null;

		ParseResult ret = null;
		try {
			is = new FileInputStream(excelFile);

			ret = readXLS(is);
		} catch (Exception ex) {
			throw new MindException("解析Excel文件出错:" + excelFile.getAbsolutePath(), ex);
		} finally {
			close(is);
		}

		return ret;

	}

	private ParseResult readXLSX(File excelFile) {
		InputStream is = null;

		ParseResult ret = null;
		try {
			is = new FileInputStream(excelFile);

			ret = readXLSX(is);
		} catch (Exception ex) {
			throw new MindException("解析Excel文件出错:" + excelFile.getAbsolutePath(), ex);
		} finally {
			close(is);
		}

		return ret;

	}

	protected void close(Closeable closeable) {
		if (closeable == null)
			return;

		try {
			closeable.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	protected abstract ParseResult readSheet(Sheet sheet);

}
